﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Reactive.Bindings.Extensions;

namespace System.Windows;

public abstract class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    protected virtual void SetProperty<T>(ref T targetField, T newValue, [CallerMemberName] string? propertyName = null)
    {
        targetField = newValue;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs propertyChangedEventArgs)
    {
        PropertyChanged?.Invoke(this, propertyChangedEventArgs);
    }
}

public abstract class ReactiveBindableBase : BindableBase, IDisposable
{
    protected CompositeDisposable Disposables { get; } = new CompositeDisposable();

    protected void TieObservable<T>(Func<IObservable<T>> register)
    {
        Disposables.Add(register.Invoke().Subscribe());
    }

    #region IDisposable

    private bool disposedValue;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                Disposables.Dispose();
            }

            disposedValue = true;
        }
    }

    // ~ReactiveBindableBase()
    // {
    //     // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
    //     Dispose(disposing: false);
    // }

    public void Dispose()
    {
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }

    #endregion IDisposable
}